package com.tx.admin.detailmodesidebar.service.impl;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import io.swagger.v3.core.util.Json;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.tx.admin.detailmodesidebar.service.DetailModeSideBarService;
import com.tx.admin.detailmodesidebar.pojo.po.DetailModeSideBar;
import com.tx.admin.detailmodesidebar.mapper.DetailModeSideBarMapper;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.tx.core.common.enums.CommonResponseEnum;
import com.tx.core.util.PageUtils;
import com.tx.core.util.BeanCopyUtils;
import com.tx.core.util.Utils;
import com.tx.core.common.entity.PageResult;
import com.tx.core.common.entity.SelectIdsDTO;
import java.io.Serializable;
import java.util.*;

import com.tx.admin.detailmodesidebar.pojo.dto.DetailModeSideBarCreateDTO;
import com.tx.admin.detailmodesidebar.pojo.dto.DetailModeSideBarUpdateDTO;
import com.tx.admin.detailmodesidebar.pojo.dto.DetailModeSideBarListDTO;
import com.tx.admin.detailmodesidebar.pojo.dto.DetailModeSideBarImportDTO;
import com.tx.core.common.entity.ImportExcelDTO;
import com.tx.excel.core.ExcelResult;
import java.io.OutputStream;
import java.util.stream.Collectors;

import jakarta.servlet.http.HttpServletResponse;
import com.tx.core.util.FileUtils;
import com.tx.excel.utils.ExcelUtils;
import lombok.SneakyThrows;
import com.tx.admin.detailmodesidebar.pojo.vo.DetailModeSideBarVO;
import org.springframework.util.CollectionUtils;

/**
 * <p>
 * 详情页树状结构 服务实现类
 * </p>
 *
 * @author sz-admin
 * @since 2025-08-05
 */
@Service
@RequiredArgsConstructor
public class DetailModeSideBarServiceImpl extends ServiceImpl<DetailModeSideBarMapper, DetailModeSideBar> implements DetailModeSideBarService {
    @Override
    public void create(DetailModeSideBarCreateDTO dto){
        DetailModeSideBar detailModeSideBar = BeanCopyUtils.copy(dto, DetailModeSideBar.class);
        save(detailModeSideBar);
    }

    @Override
    public void update(DetailModeSideBarUpdateDTO dto){
        DetailModeSideBar detailModeSideBar = BeanCopyUtils.copy(dto, DetailModeSideBar.class);
        QueryWrapper wrapper;
        // id有效性校验
        wrapper = QueryWrapper.create()
            .eq(DetailModeSideBar::getId, dto.getId());
        CommonResponseEnum.INVALID_ID.assertTrue(count(wrapper) <= 0);

        saveOrUpdate(detailModeSideBar);
    }

    @Override
    public PageResult<DetailModeSideBarVO> page(DetailModeSideBarListDTO dto){
        Page<DetailModeSideBarVO> page = pageAs(PageUtils.getPage(dto), buildQueryWrapper(dto), DetailModeSideBarVO.class);
        return PageUtils.getPageResult(page);
    }

    @Override
    public List<DetailModeSideBarVO> list(DetailModeSideBarListDTO dto){
        return listAs(buildQueryWrapper(dto), DetailModeSideBarVO.class);
    }

    @Override
    public void remove(SelectIdsDTO dto){
        CommonResponseEnum.INVALID_ID.assertTrue(dto.getIds().isEmpty());
        removeByIds(dto.getIds());
    }

    @Override
    public DetailModeSideBarVO detail(Object id){
        DetailModeSideBar detailModeSideBar = getById((Serializable) id);
        CommonResponseEnum.INVALID_ID.assertNull(detailModeSideBar);
        return BeanCopyUtils.copy(detailModeSideBar, DetailModeSideBarVO.class);
    }

    @SneakyThrows
    @Override
    public void importExcel(ImportExcelDTO dto) {
        ExcelResult<DetailModeSideBarImportDTO> excelResult = ExcelUtils.importExcel(dto.getFile().getInputStream(), DetailModeSideBarImportDTO.class, true);
        List<DetailModeSideBarImportDTO> list = excelResult.getList();
        List<String> errorList = excelResult.getErrorList();
        String analysis = excelResult.getAnalysis();
        System.out.println(" analysis : " + analysis);
        System.out.println(" isCover : " + dto.getIsCover());
    }

    @SneakyThrows
    @Override
    public void exportExcel(DetailModeSideBarListDTO dto, HttpServletResponse response) {
        List<DetailModeSideBarVO> list = list(dto);
        String fileName = "详情页树状结构模板";
        OutputStream os = FileUtils.getOutputStream(response, fileName + ".xlsx");
        ExcelUtils.exportExcel(list, "详情页树状结构", DetailModeSideBarVO.class, os);
    }

    @Override
    public DetailModeSideBarVO orderTrees(Long masterId) {
        DetailModeSideBarVO vo = new DetailModeSideBarVO();
        QueryWrapper wrapper = QueryWrapper.create().from(DetailModeSideBar.class);
        List<DetailModeSideBar> list = list(wrapper.eq(DetailModeSideBar::getExt1, masterId));
        if (CollectionUtils.isEmpty(list)){
            return vo;
        }
        List<DetailModeSideBarVO> vos = BeanCopyUtils.copyList(list, DetailModeSideBarVO.class);

        Map<Long, List<DetailModeSideBarVO>> sons = vos.stream().filter(s -> Objects.nonNull(s.getParentId()))
                .toList().stream().collect(Collectors.groupingBy(DetailModeSideBarVO::getParentId));
        sons.replaceAll((key, value) -> value.stream()
                .sorted(Comparator.comparing(DetailModeSideBarVO::getExt))
                .collect(Collectors.toList()));

        List<DetailModeSideBar> fathers = list.stream().filter(s -> Objects.isNull(s.getParentId())).toList();
        List<DetailModeSideBarVO> fathervos = BeanCopyUtils.copyList(fathers, DetailModeSideBarVO.class);
        List<JSONObject> jsonObjects = new ArrayList<>();
        setFatherSons(fathervos,sons,jsonObjects);

        vo.setTrees(fathervos);
        vo.setContexts(jsonObjects);

        return vo;
    }

    private void setFatherSons(List<DetailModeSideBarVO> fathers, Map<Long, List<DetailModeSideBarVO>> sons, List<JSONObject> jsonObjects) {
        fathers.forEach(s->{
            assembleEditBox(jsonObjects, s);
            s.setTitle(s.getLabel());
            List<DetailModeSideBarVO> detailModeSideBars = sons.getOrDefault(s.getId(),new ArrayList<>());
            s.setChildren(detailModeSideBars);
            setFatherSons(detailModeSideBars,sons, jsonObjects);
        });
    }

    private static QueryWrapper buildQueryWrapper(DetailModeSideBarListDTO dto) {
        QueryWrapper wrapper = QueryWrapper.create().from(DetailModeSideBar.class);
        if (Utils.isNotNull(dto.getParentId())) {
            wrapper.eq(DetailModeSideBar::getParentId, dto.getParentId());
        }
        if (Utils.isNotNull(dto.getLabel())) {
            wrapper.eq(DetailModeSideBar::getLabel, dto.getLabel());
        }
        if (Utils.isNotNull(dto.getExt())) {
            wrapper.eq(DetailModeSideBar::getExt, dto.getExt());
        }
        if (Utils.isNotNull(dto.getExt1())) {
            wrapper.eq(DetailModeSideBar::getExt1, dto.getExt1());
        }
        if (Utils.isNotNull(dto.getExt2())) {
            wrapper.eq(DetailModeSideBar::getExt2, dto.getExt2());
        }
        if (Utils.isNotNull(dto.getExt3())) {
            wrapper.eq(DetailModeSideBar::getExt3, dto.getExt3());
        }
        if (Utils.isNotNull(dto.getExt4())) {
            wrapper.eq(DetailModeSideBar::getExt4, dto.getExt4());
        }
        if (Utils.isNotNull(dto.getExt5())) {
            wrapper.eq(DetailModeSideBar::getExt5, dto.getExt5());
        }
        if (Utils.isNotNull(dto.getExt6())) {
            wrapper.eq(DetailModeSideBar::getExt6, dto.getExt6());
        }
        if (Utils.isNotNull(dto.getExt7())) {
            wrapper.eq(DetailModeSideBar::getExt7, dto.getExt7());
        }
        return wrapper;
    }

    private static void assembleEditBox(List<JSONObject> jsonObjects, DetailModeSideBarVO s) {
        JSONObject object = JSONUtil.parseObj(s);
        object.put("title", s.getLabel());
        if (Objects.equals(s.getExt2(),1)){
            object.put("indexModel","titleOne");
        }else if (Objects.equals(s.getExt2(),2)){
            object.put("indexModel","titleTwo");
        }else if (Objects.equals(s.getExt2(),3)){
            object.put("indexModel","context");
        }
        jsonObjects.add(object);
    }
}